##########################################
## Copyright 2012-2013 Ceruti Francesco
##
##
## This file is part of LiSP (Linux Show Player).
##
## LiSP (Linux Show Player) is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## LiSP (Linux Show Player) is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with LiSP (Linux Show Player).  If not, see <http://www.gnu.org/licenses/>.
##########################################

from PyQt4 import QtCore
from uuid import uuid4


class Media(QtCore.QObject):
    '''
    An Abstract base for all the media on the software system.
    The "emit" parameter is used for decide when a signal should be emit.
    '''

    '''
    Media status: describe the current media state.
    Can be different from the effective playback state.
    '''
    PLAYING = 3  # Media in play
    PAUSED = 2  # Media in pause
    STOPPED = 1  # Media ready for playback
    NONE = 0  # Media not configured

    '''
    The MEDIA_DEFAULT_CONF provide a set of configuration parameters needed for use a media properly.
    For add parameters on subclasses use: Media.MEDIA_CONF.update(dict).
    NOTE: __init__() add "uuid" to Media.conf, this property is not in MEDIA_DEFAULT_CONF because
        no default value is needed.
    '''
    MEDIA_DEFAULT_CONF = {'name': 'Empty Media',
                          'location': '',
                          'groups': [],
                          'stopAll': False}

    '''
    PyQt-provided signals:
        for thread-safe usage   -> signal.connect(callable, QtCore.Qt.QueuedConnection)
        for normal usage        -> signal.connect(callable)
        for info see PyQt documentation

    General purposes signals: can be used in every part of software,
    because, when emit, the signal give the specific media.
    '''
    onPlay = QtCore.pyqtSignal(object)  # Media go in play state
    onStop = QtCore.pyqtSignal(object)  # Media go in stop state
    onStopped = QtCore.pyqtSignal(object)  # Media playback is stopped
    onPause = QtCore.pyqtSignal(object)  # Media go in puase state
    onPaused = QtCore.pyqtSignal(object)  # Media playback is paused
    onSeek = QtCore.pyqtSignal(object, int)  # Media is sought
    onEndOfStream = QtCore.pyqtSignal(object)  # Media stream ended
    onError = QtCore.pyqtSignal(object, str)  # Media error
    '''
    Specific signals: can be used when you know the media that emit the signals.
    For example in a Widget that show the media status.
    '''
    onDuration = QtCore.pyqtSignal(int)  # Media duration changed
    onFadeOut = QtCore.pyqtSignal(bool)  # Media in/out fade-out
    onFadeIn = QtCore.pyqtSignal(bool)  # Media in/out fade-in
    onConfigurationChanged = QtCore.pyqtSignal()  # Media configuration changed

    state = NONE  # current media state
    conf = {}  # current media configuration. DON'T OVVERIDE, use only dict.update(dict)

    def __init__(self):
        super(Media, self).__init__()

        self.conf['uuid'] = str(uuid4())

    def currentTime(self):
        '''Get the current playback time, or -1 for error'''

    def interrupt(self, reconf=True):
        '''Stop the media without notification or effects'''

    def pause(self, emit=True):
        '''Go in pause state'''

    def play(self, emit=True):
        '''Go in play state'''

    def seek(self, seek_time, emit=True):
        '''Seek to time (unit depends from extension)'''

    def setConfiguration(self, conf, emit=True):
        '''Change the configuration'''

    def stop(self, emit=True):
        '''Go in stop state'''
